package com.code.refactoring.spring相关.aop相关;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;

/**
 * description:
 * author: wangxi
 * date:  2022/4/6 4:56 下午
 **/
@Component
@Slf4j
public class RetryService {

    @Autowired
    private ApplicationContext applicationContext;

    /**
     * 经过打断点调试，看到了this对象与 currentProxy1，currentProxy2 是不同的：
     *  this就是当前对象 RetryService
     *  currentProxy1，currentProxy2 相同，都是cglib的代理对象：RetryService$$EnhancerBySpringCglib
     */

    public void fun01() {
//        this.fun02();    // 此种不会重试，相当于利用this对象调用
        log.info("{}",this.hashCode());    // hashcode不一致
        // toString方法当前对象与 代理对象的值一样的。。
        log.info("{}",this.toString());

        RetryService currentProxy1 = applicationContext.getBean(RetryService.class); // 经过spring容器处理了
        RetryService currentProxy2 = (RetryService) AopContext.currentProxy();
        log.info("{}", currentProxy1.hashCode());
        log.info("=====================");
//        currentProxy1.fun02();   // 此种也不会重试
        log.info("{}",currentProxy2.hashCode());
        log.info("=====================");
//        currentProxy2.fun02();    // 此种也不会重试
        
        currentProxy2.fun002();   // 此种会重试
    }


    @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000, multiplier = 1.5))
    private void fun02() {
        log.info("======fun02......");
        int a = 1/0;
    }
    
    // 需要是public方法，否则cglib无法继承子类进行代理
    @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000, multiplier = 1.5))
    public void fun002() {
        log.info("======fun02......");
        int a = 1/0;
    }

    @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000, multiplier = 1.5))
    public void fun03() {
        log.info("======fun03......");
        int a = 1/0;
    }
}
